package com.lenovo.nova.util.network;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.UnknownHostException;
import java.util.List;

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.conn.params.ConnRoutePNames;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;

import android.content.Context;

import com.lenovo.nova.util.debug.MyOldLog;

/**
 * apache 联网的底层处理
 * @author liuzhd
 */
public class ApacheNetworkManager {
	protected static final String RESPONDHEAD_COOKIE = "Set-Cookie";
	
	private HttpClient httpClient;
	
	/**
	 * 联网的类型
	 */
	private int connType;
	
	/**
	 * 网络超时时间
	 */
	private static final int CONNECT_TIMEOUT = 120 * 1000;

	/**
	 * 读取超时时间
	 */
	private static final int READ_TIMEOUT = 120 * 1000;

	private Context context;

	public ApacheNetworkManager(Context context) {
		this.context = context;
		connType = NetworkUtils.getConnectType(context);
		httpClient = getApacheClient(connType);
	}

	/**
	 * @param isPost -- 判断是否是post请求（暂时只支持get和post两种）
	 * @param url
	 * @param requestHead -- 请求的消息报头
	 * @param postBody -- 请求正文
	 * @return
	 * @throws Exception
	 */
	public HttpResponse getResponse(int connectionType, boolean isPost, String url, List<BasicNameValuePair> requestHead, List<BasicNameValuePair> postBody) {
		// 接受服务器的回应
		HttpRequestBase httpRequest;
		if (isPost) {
			httpRequest = new HttpPost(url);
			if (postBody != null) {
				try {
					((HttpPost) httpRequest).setEntity(new UrlEncodedFormEntity(postBody, HTTP.UTF_8));
				} catch (UnsupportedEncodingException e) {
					MyOldLog.error(this, "URL格式化错误   postBody is " + postBody + "   " + e);
					// e.printStackTrace();
				}
			}
		} else {
			httpRequest = new HttpGet(url);
		}
		System.out.println("url is " + url);
		if (requestHead != null) {
			for (BasicNameValuePair basicNameValuePair : requestHead) {
				httpRequest.addHeader(basicNameValuePair.getName(), basicNameValuePair.getValue());
			}
		}

		HttpResponse httpResponse = null;
		try {
			httpResponse = httpClient.execute(httpRequest);
		} catch (UnknownHostException e) {
			MyOldLog.error(this, "getResponse(): UnknownHostException " + e + "  没有网络 连接");
		} catch (ConnectTimeoutException e){
			MyOldLog.e("ConnectTimeoutException " + e);
		} catch (Exception e) {
			MyOldLog.error(this, "getResponse(): IOException " + e);
		}
		
		return httpResponse;
	}

	/**
	 * 关闭连接
	 */
	public void cloaseApachConn(){
		httpClient.getConnectionManager().shutdown();
	}
	
	
	public int getConnType(){
		return connType;
	}
	
	/**
	 * Post的方式连接网
	 * 
	 * @param isPost 是否使用Post连接网络，true是用post连接，false是用get连接
	 * @param strUrl 网络的地址
	 * @param requestHead 请求的消息报头
	 * @param postBody 请求正文
	 * @param respondHead 响应的消息报头
	 * @return 返回服务器回应的消息正文，如果联网失败的话就返回NUll
	 * @throws
	 */
	public synchronized String connectionWithApache(boolean isPost, String strUrl, List<BasicNameValuePair> requestHead, List<BasicNameValuePair> postBody, List<BasicNameValuePair> respondHead) {
		// 取得联网的类型
		int connectionType = NetworkUtils.getConnectType(context);
		if(connectionType != this.connType){
			this.httpClient = getApacheClient(connectionType);
		}
		HttpResponse httpResp = getResponse(connectionType, isPost, strUrl, requestHead, postBody);

		// 如果是wap的话，有可能是移动的网管数据，这里要检测下
		String result = getStringByHttpRequest(httpResp);
		if (connectionType == NetworkUtils.CONNECTION_TYPE_WAP) {
			int reConnectionTime = 0;
			while (result == null || result.startsWith("<")) {
				// 连接超时或者收到了网管的数据，要重新连接
				httpResp = getResponse(connectionType, isPost, strUrl, requestHead, postBody);
				result = getStringByHttpRequest(httpResp);
				reConnectionTime++;
				MyOldLog.log(this, "返回结果是 " + result + " 重连第 " + reConnectionTime + " 次");
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				if (reConnectionTime > 3) {
					return null;
				}
			}

		}
		// 此时联网失败了
		if (httpResp == null) {
			MyOldLog.error(this, "getResponse 返回的是空值，此时联网错误了，没有网络，或者信号差");
			return null;
		}
		if (null != respondHead) {
			// 设置回应的状态行
			respondHead.add(new BasicNameValuePair("StatusLine", httpResp.getStatusLine().toString()));

			// 下面设置回应的消息报头
			for (Header header : httpResp.getAllHeaders()) {
				respondHead.add(new BasicNameValuePair(header.getName(), header.getValue()));
			}
		}

		// 响应正文
		MyOldLog.log(this, "connectionWithApache  : 回应的正文内容是 " + result);
		return result;
	}

	private String getStringByHttpRequest(HttpResponse httpResp) {
		if (httpResp == null) {
			return null;
		}
		HttpEntity entity = httpResp.getEntity();

		byte[] data = null;
		try {
			data = EntityUtils.toByteArray(entity);
		} catch (IOException e) {
			MyOldLog.error(this, "connectionWithApache(): " + e);
			e.printStackTrace();
		}
		String result = null;
		try {
			result = new String(data, "UTF-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return result;
	}

	/**
	 *获取apache的客户端
	 * @return
	 */
	private HttpClient getApacheClient(int connectionType) {
		HttpParams httpParamas = new BasicHttpParams();

		// 设置代理
		if (connectionType == NetworkUtils.CONNECTION_TYPE_WAP) {
			// cmwap连接网络

			MyOldLog.log(this, "wap连网");
			String host = android.net.Proxy.getDefaultHost();
			int port = android.net.Proxy.getDefaultPort();
			if (host != null && port != -1) {
				httpParamas.setParameter(ConnRoutePNames.DEFAULT_PROXY, new HttpHost(host, port));
			}
		} else if (connectionType == NetworkUtils.CONNECTION_TYPE_NO_CONNECT) {
			MyOldLog.log(this, "没有打开网络连接");
		} else {
			MyOldLog.log(this, "wifi或者net联网");
		}

		// 设置超时时间
		HttpConnectionParams.setConnectionTimeout(httpParamas, CONNECT_TIMEOUT);
		HttpConnectionParams.setSoTimeout(httpParamas, READ_TIMEOUT);
		return new DefaultHttpClient(httpParamas);
	}


}
